package com.biodiv.miracle.support.utils;

import com.biodiv.miracle.ioc.context.ApplicationContext;
import com.biodiv.miracle.ioc.factory.FactoryBean;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @Author: tianquan
 * @date: 2024-09-29  12:17
 * @Description: 框架工具类
 */
public class MiracleUtils {

    private static ApplicationContext applicationContext;

    private static final ClassLoader CLASS_LOADER = Thread.currentThread().getContextClassLoader();

    public static void init(ApplicationContext applicationContext) {
        MiracleUtils.applicationContext = applicationContext;
    }

    public static ClassLoader getClassLoader() {
        return CLASS_LOADER;
    }

    /**
     * 根据类生成bean名称。
     *
     * @param clazz 类对象。
     * @return 生成的bean名称。
     */
    public static String createBeanName(Class<?> clazz) {
        // 给代理对象生成beanName
        if (clazz.getName().contains("$")) {
            return clazz.getSimpleName().toLowerCase();
        }
        // 普通对象
        String name = clazz.getName();
        String beanName = name.substring(name.lastIndexOf(".") + 1);
        return beanName.substring(0, 1).toLowerCase() + beanName.substring(1);
    }


    public static String createBeanName(Annotation annotation, Class<?> clazz) {
        String beanName = null;
        Method valueMethod = null;
        // 获取注解的value方法
        try {
            if (annotation != null) {
                valueMethod = annotation.getClass().getMethod("value");
            }
        } catch (NoSuchMethodException e) {
        }
        // 获取注解的value属性值
        if (valueMethod != null) {
            valueMethod.setAccessible(true);
            try {
                beanName = (String) valueMethod.invoke(annotation);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        if (beanName != null && !beanName.isEmpty()) {
            return beanName;
        } else {
            beanName = MiracleUtils.createBeanName(clazz);
        }
        if (FactoryBean.class.isAssignableFrom(clazz)) {
            beanName = "&" + beanName;
        }
        return beanName;
    }

    public static String getPropertiesValue(String name) {
        return applicationContext.getEnvironmentVariable(name);
    }

    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }

    public static Object getBean(Class<?> clazz) {
        return applicationContext.getBean(clazz);
    }

    public static void registerBean(String name, Object bean) {
        applicationContext.registerBean(name, bean);
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }


}
